﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace SocketClient
{
    public partial class frmReplyItem : Form
    {

        #region frmReplyItem
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ownerReplyGroup"></param>
        public frmReplyItem(ReplyGroup ownerReplyGroup)
        {
            InitializeComponent();
            Init();
            this.ReplyItem.ReplyGroup = ownerReplyGroup;
        }
        #endregion //frmReplyItem

        #region frmReplyItem
        /// <summary>
        /// 
        /// </summary>
        /// <param name="replyItem"></param>
        public frmReplyItem(ReplyItem replyItem)
        {

            if (replyItem == null)
            {
                throw new ArgumentNullException("replyItem");
            }

            InitializeComponent();
            Init();


            this.ReplyItem = replyItem;

            this.IsEdit = true;
        }
        #endregion //frmReplyItem

        private void Init()
        {
            this.Size = App.Default.Config.ReplyItemSize;
        }

        #region frmReplyItem_Load
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmReplyItem_Load(object sender, EventArgs e)
        {

            FillCrcComboBox();
            InitGroupComboBox();

            this.cmbGroup.SelectedItem = this.ReplyItem.ReplyGroup;

            string s = string.Format(
                "{0} - {1}",
                Strings.Reply,
                _isEdit ? Strings.Edit : Strings.Add);
            this.Text = s;

            if (_isEdit)
            {
                this.txtName.Text = this.ReplyItem.Name;
                this.txtReceived.Text = this.ReplyItem.ReceivedPattern;
                this.txtReply.Text = HexStringConverter.Default.ConvertToObject(this.ReplyItem.ReplyBytes).ToString();
                this.txtDescription.Text = this.ReplyItem.Description;
            }
        }
        #endregion //frmReplyItem_Load

        #region FillCrcComboBox
        /// <summary>
        /// 
        /// </summary>
        private void FillCrcComboBox()
        {
            // fill crc
            //
            var crcKvs = new List<KeyValuePair<string, Type>>();
            crcKvs.Add(new KeyValuePair<string, Type>(typeof(CRC16).Name, typeof(CRC16)));
            crcKvs.Add(new KeyValuePair<string, Type>(typeof(CRCSum).Name, typeof(CRCSum)));
            crcKvs.Add(new KeyValuePair<string, Type>(typeof(CRCXor).Name, typeof(CRCXor)));

            this.cmbCrc.DisplayMember = "Key";
            this.cmbCrc.ValueMember = "Value";
            this.cmbCrc.DataSource = crcKvs;
        }
        #endregion //FillCrcComboBox

        #region InitGroupComboBox
        /// <summary>
        /// 
        /// </summary>
        private void InitGroupComboBox()
        {
            this.cmbGroup.DropDownStyle = ComboBoxStyle.DropDown;
            this.cmbGroup.DisplayMember = "Name";
            ReplyGroupManager.Instance.ReplyGroups.Sort();
            this.cmbGroup.DataSource = ReplyGroupManager.Instance.ReplyGroups;
        }
        #endregion //InitGroupComboBox

        #region IsEdit
        /// <summary>
        /// 
        /// </summary>
        public bool IsEdit
        {
            get
            {
                return _isEdit;
            }
            set
            {
                _isEdit = value;
            }
        } private bool _isEdit;
        #endregion //IsEdit

        #region ReplyItem
        /// <summary>
        /// 
        /// </summary>
        public ReplyItem ReplyItem
        {
            get
            {
                if (_replyItem == null)
                {
                    _replyItem = new ReplyItem();
                }
                return _replyItem;
            }
            set
            {
                _replyItem = value;
            }
        } private ReplyItem _replyItem;
        #endregion //ReplyItem

        #region txtReceived_KeyPress
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtReceived_KeyPress(object sender, KeyPressEventArgs e)
        {
            KeyPressHelper.Process(sender, e);
        }
        #endregion //txtReceived_KeyPress

        #region txtReply_KeyPress
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtReply_KeyPress(object sender, KeyPressEventArgs e)
        {
            KeyPressHelper.Process(sender, e);
        }
        #endregion //txtReply_KeyPress

        #region btnOK_Click
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOK_Click(object sender, EventArgs e)
        {
            byte[] received, reply;
            try
            {
                received = (byte[])HexStringConverter.Default.ConvertToBytes(txtReceived.Text);
                reply = (byte[])HexStringConverter.Default.ConvertToBytes(txtReply.Text);
            }
            catch (Exception ex)
            {
                NUnit.UiKit.UserMessage.DisplayFailure(ex.Message);
                return;
            }

            if (received.Length == 0 || reply.Length == 0)
            {
                NUnit.UiKit.UserMessage.DisplayFailure(Strings.ReceivedReplyLengthZero);
                return;
            }

            this.ReplyItem.ReplyGroup = GetSelectedReplyGroup();
            this.ReplyItem.Name = this.txtName.Text.Trim();
            this.ReplyItem.ReceivedPattern = HexStringConverter.Default.ConvertToObject(received).ToString();
            this.ReplyItem.ReplyBytes = reply;
            this.ReplyItem.Description = this.txtDescription.Text.Trim();

            this.DialogResult = DialogResult.OK;
            this.Close();
        }
        #endregion //btnOK_Click

        #region GetSelectedReplyGroup
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private ReplyGroup GetSelectedReplyGroup()
        {
            return ReplyGroupManager.Instance[this.cmbGroup.Text];
        }
        #endregion //GetSelectedReplyGroup

        #region txtReply_TextChanged
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtReply_TextChanged(object sender, EventArgs e)
        {
            var c = CalcHexStringBytesCount(txtReply.Text);
            this.lblReplyBytesCount.Text = string.Format(
                "{0} bytes", c);

            this.lblReplyBytesCount.ForeColor = c == 0 ? Color.Red : Color.Blue;
        }
        #endregion //txtReply_TextChanged

        #region CalcHexStringBytesCount
        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private int CalcHexStringBytesCount(string s)
        {
            try
            {
                var bs = HexStringConverter.Default.ConvertToBytes(s);
                return bs.Length;
            }
            catch
            {
                return 0;
            }
        }
        #endregion //CalcHexStringBytesCount

        #region btnCalcCrc_Click
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCalcCrc_Click(object sender, EventArgs e)
        {
            byte[] bs = null;

            try
            {
                bs = HexStringConverter.Default.ConvertToBytes(txtReply.Text);
            }
            catch
            {
                return;
            }

            if (bs.Length >0 && this.cmbCrc.SelectedIndex >= 0)
            {
                Type t = this.cmbCrc.SelectedValue as Type;
                var crc = (SD.Common.ICrc)Activator.CreateInstance(t);
                var crcBs = crc.Calc(bs, 0, bs.Length);

                var crcText = (string)HexStringConverter.Default.ConvertToObject(crcBs);

                if (!LastCharIsSplit(txtReply.Text))
                {
                    txtReply.AppendText(" ");
                }
                txtReply.AppendText(crcText);
            }
        }
        #endregion //btnCalcCrc_Click

        #region LastCharIsSplit
        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private bool LastCharIsSplit(string s)
        {
            if (s.Length > 0)
            {
                var c = s[s.Length - 1];
                return c == ' ' || c == '-';
            }
            else
            {
                return true;
            }
        }
        #endregion //LastCharIsSplit

        private void frmReplyItem_FormClosing(object sender, FormClosingEventArgs e)
        {
            App.Default.Config.ReplyItemSize = this.Size;
        }
    }
}
